/*
 * 础石Hypervisor -- 设备树头文件
 *
 * Copyright (C) 2006 David Gibson, IBM Corporation.
 * Copyright 2012 Kim Phillips, Freescale Semiconductor.
 * Copyright (C) 2022 国科础石(重庆)软件有限公司
 *
 * 作者: Xueming Dong <dongxueming@kernelsoft.com>
 *       Jingchen Zhong <zhongjingchen@kernelsoft.com>
 *
 * License terms: GNU General Public License (GPL) version 3
 *
 */

#ifndef __DIM_SUM_FDT_H
#define __DIM_SUM_FDT_H

#include <dim-sum/types.h>
#include <dim-sum/devtree.h>

#ifndef __ASSEMBLY__

struct fdt_header {
	u32 magic;		
	u32 totalsize;		
	u32 off_dt_struct;	
	u32 off_dt_strings;	
	u32 off_mem_rsvmap;	
	u32 version;		
	u32 last_comp_version;

	u32 boot_cpuid_phys;
	u32 size_dt_strings;	

	u32 size_dt_struct;
};

struct fdt_reserve_entry {
	u64 address;
	u64 size;
};

struct fdt_node_header {
	u32 tag;
	char name[0];
};

struct fdt_property {
	u32 tag;
	u32 len;
	u32 nameoff;
	char data[0];
};

#endif /* !__ASSEMBLY */

#define FDT_MAGIC	0xd00dfeed	/* 4: 版本, 4: 总大小 */
#define FDT_TAGSIZE	sizeof(u32)

#define FDT_BEGIN_NODE	0x1	
#define FDT_END_NODE	0x2	
#define FDT_PROP	    0x3	
#define FDT_NOP		    0x4	
#define FDT_END		    0x9

#define FDT_V1_SIZE	(7*sizeof(u32))
#define FDT_V2_SIZE	(FDT_V1_SIZE + sizeof(u32))
#define FDT_V3_SIZE	(FDT_V2_SIZE + sizeof(u32))
#define FDT_V16_SIZE	FDT_V3_SIZE
#define FDT_V17_SIZE	(FDT_V16_SIZE + sizeof(u32))


typedef u32 fdt_cell_t;


struct fdt_fileinfo {
	struct fdt_header header;
	char *data;
	size_t data_size;
	char *str;
	size_t str_size;
	char *mem_rsvmap;
	u32 mem_rsvcnt;
};

int libfdt_parse_fileinfo(void *fdt_addr, struct fdt_fileinfo *fdt);

int libfdt_populate_devtree(struct fdt_fileinfo *fdt,
			 struct device_node **root,
			 const char *root_name,
			 struct device_node *root_parent);

u32 libfdt_reserve_count(struct fdt_fileinfo *fdt);

int libfdt_reserve_address(struct fdt_fileinfo *fdt, u32 index, u64 *addr);

int libfdt_reserve_size(struct fdt_fileinfo *fdt, u32 index, u64 *size);

struct fdt_node_header *libfdt_find_matching_node(struct fdt_fileinfo *fdt,
			int (*match)(struct fdt_node_header *, int, void *),
			void *priv);

struct fdt_node_header *libfdt_find_node(struct fdt_fileinfo *fdt,
					 const char *node_path);

void *libfdt_get_property(struct fdt_fileinfo *fdt,
			struct fdt_node_header *fdt_node,
			const char *name, u32 *len);

#endif /* __DIM_SUM_FDT_H */
